home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 25
/
Cream of the Crop 25.iso
/
os2
/
srefv12i.zip
/
ssicache.rxx
< prev
next >
Wrap
Text File
|
1997-01-09
|
17KB
|
504 lines
s/* The ssi-caching thread, for SRE-FILTER.
Uses workdata_temp for storage
call with queue containing:
transaction ' ' host_nickname ',' newq ',' newsem ',' filename
returns
status ' ' filename
status=0 : no match
1 : use filename as is
2 : read filename, and continue to do ssi's
*/
parse upper arg storage_dir, usequeue , USESEM, max_semwait,port,cache_size,def_duration,def_trigtype
storage_dir=strip(storage_dir,'t','\')
cache_list.0=0 ; cache_list.!size=0 ; cache_list.!marked=0
max_marked=8 /* cleanup after this many expirations, etc. */
call pmprintf(' SRE-FILTER ssi-cache thread: ssi_cache dir='||storage_dir)
mytid=dostid()
call pmprintf(' SRE-FILTER ssi-cache thread: queue='||usequeue)
call pmprintf(' SRE-FILTER ssi-cache thread: semaphore='||usesem)
call pmprintf(' SRE-FILTER ssi-cache thread: thread id ='||mytid)
if storage_dir="" | usequeue="" | USESEM="" then do
call pmprintf('SRE-FILTER ssi-cache thread: initialization ERROR: '||usequeue)
exit
end
/* clear junk from cache storage directory */
oo=sysfiletree(storage_dir||'\_CSH*.'||port,oofs,'FO')
do mm=1 to oofs.0
foo=sysfiledelete(oofs.mm)
end
call pmprintf(' SRE-Filter ssi-cache thread: Deleted 'oofs.0' old cache files')
drop oofs.
/* Initialization now done == start waiting for requests for ssi-cache */
signal on error name iserror
signal on syntax name iserror
idid=0
bakme:
a=rxqueue('s',usequeue)
aq=queued()
if aq=0 then do
WOW=EVENTSEM_WAIT(USESEM,max_semwait)
aq=-1
if wow=640 then do
signal bakme
end
IF WOW<>0 THEN do /* FATAL ERROR */
call pmprintf(' SRE-Filter ssi-cache Thread: fatal semaphore error: 'wow)
EXIT
end
end
wow=EVENTSEM_RESET(usesem)
if aq=-1 then
if queued()=0 then signal bakme
PARSE pull isit0
isit0=translate(isit0,' ','000d0a09'x)
if isit0=" " then signal bakme
/* die command? */
if abbrev(isit0,'*DIE*')=1 then
exit
goobs:
parse var isit0 idnum ',' newq ',' newsem ',' anfile addto
addto=strip(addto);anfile=strip(anfile) ;
parse var idnum idnum host_nickname
host_nickname=strip(upper(host_nickname))
if newq="" | newsem="" then do
call pmprintf(' SRE-FILTER ssi-cache thread: missing queue or semaphore ')
exit
end
newq=upper(strip(newq)); newsem=upper(strip(newsem))
anfile=upper(strip(anfile))
/* do something ... */
select
when abbrev(anfile,'*RESET')=1 then do
do mm=1 to cache_list.0
foo=sysfiledelete(cache_list.mm.!dafile)
end
foo=cache_list.0
foo2=cache_list.!size
drop cache_list.
cache_list.0=0 ; cache_list.!size=0 ; cache_list.!marked=0
call lineout addto,' SRE-Filter ssi-cache: cleared ' foo2 ' bytes in ' foo ' files in:' storage_dir
call lineout addto
a=rxqueue('s',newq)
push idnum ',' 1
wow=eventsem_post(newsem)
end
when abbrev(anfile,'*STATUS')=1 then do
foo=do_status(anfile)
a=rxqueue('s',newq)
push idnum ',' 1
wow=eventsem_post(newsem)
end
when abbrev(anfile,'*CLEANUP')=1 then do
foo=shrink_cache(1,addto)
a=rxqueue('s',newq)
push idnum ',' 1
wow=eventsem_post(newsem)
end
/* get rid of old entries? */
when abbrev(anfile,'*REMOVE')=1 then do
removes=substr(anfile,8)
removes=translate(removes,' ','+='||'000d0a'x)
removes=packur(removes); removes=upper(translate(removes,'\','/'))
do mm=1 to words(removes)
arem=strip(word(removes,mm))
call lineout addto,' Attempting to remove from SSI-cache: ' arem
do meow=1 to cache_list.0
if cache_list.meow=arem & cache_list.meow.!host=host_nickname then do
wass=cache_list.meow.!size
foo=cache_del(meow)
call lineout addto,' .... removed ' arem '( ' wass ' bytes) from SSI-cache '
end
end
call lineout addto
a=rxqueue('s',newq)
push idnum ',' 1
wow=eventsem_post(newsem)
end
end
otherwise do /* look up a cache entry!!!!!!! */
a=rxqueue('s',newq)
dog1=get_from_ssi_cache(anfile,addto)
if addto=' ' then do
push idnum ',' dog1
wow=eventsem_post(newsem)
end /* if ADD, no return expected */
end /* otherwiase */
end /* selekct */
signal bakme
iserror:
signal off error ; signal off syntax
foo=condition('d')
call pmprintf(' SRE-FIlter: error in ssi-cache thread 'foo)
n1=queued()
a=rxqueue('d',usequeue)
a=rxqueue('c',usequeue)
foo=eventsem_reset(usesem)
a=eventsem_close(usesem)
a=eventsem_create(usesem)
a=rxqueue('s',newq)
push idnum ', 0 '
wow=eventsem_post(newsem)
call pmprintf('SRE-Filter: done resetting ssi-cache thread ')
signal on error name iserror
signal on syntax name iserror
signal bakme
exit
/***********/
/* anfile = file to be looked for
dafile = a "temporary" file used that should be stored in the cache
fields of cache_list.
.0 = # entries
.!size= Running totals: kbytes
.!marked= Marked for deletion
.m = name of file "to be cached" (anfile) -- or =0 if marked for deletion
.m.!type = type of file (1=use as is, 2=process further)
.m.!time = time file was created
.m.!host= host nickname for this entry
.m.!recent = most recent access
.m.!size = size of Cached-file (the _CSH*.80 file)
.m.!duration = lifespan of this file
.m.!ntriggers = # of trigger files (usually =1 : own file name )
.m.!trigger.n = A trigger file stamp: date size attribs fully_qualified_name
.m.!trigtype = Type of trigger (DATE TIME TIMEDATE DATETIME SIZE ALL)
.m.!dafile = The "cached" (_CSH*.80) file
*/
get_from_ssi_cache:procedure expose cache_list. storage_dir def_duration cache_size def_trigtype ,
host_nickname max_marked
parse upper arg anfile,todo
inc=cache_list.0
nowtime=date('b')+(time('m')/(24*60))
/* ======== Here to add a file to the cache */
if todo<>' ' then do
itype=2 /* assume changes will be necessary */
parse var todo dafile al
dafile=strip(dafile)
triggers=anfile
duration=def_duration ; trigtype=def_trigtype
do until al=""
parse var al val ';' al
val=upper(strip(val))
val1=strip(word(val,1))
if val="ASIS" then do /* asis must be explicitly invoked by CACHE ASIS */
itype=1
end
if val="NOCHANGE" then itype=1 /* no change occurs if all static ssis */
if val1="TRIGGER" then triggers=triggers||' '||subword(val,2)
if val1="TRIGGER_TYPE" then trigtype=strip(word(val,2))
if val1="DURATION" | val1="DAYS" then duration=strip(word(val,2))
if val1="HOURS" then do
duration=word(val,2)
if datatype(duration)="NUM" then duration=duration/24 ;
end
end
/* done with file specific options */
if datatype(duration)<>'NUM' then duration=def_duration
/* NOte:itype=1 means "return as is"*/
dafilesize=chars(dafile); foo=stream(dafile,'c','close')
if dafilesize=0 then return 0 /* no such entry */
if dafilesize>(cache_size*500) then do
foo=sysfiledelete(dafile)
return ' ' /* too big */
end
/* size is not a problem,save results */
inc=inc+1
cache_list.inc=anfile
cache_list.inc.!host=host_nickname
cache_list.inc.!type=itype /* 1= use as is */
cache_list.inc.!ntriggers=0
cache_list.inc.!duration=duration
cache_list.inc.!time=nowtime /*the creation time stamp */
cache_list.inc.!recent=nowtime /* the most recent hit time stamp */
cache_list.inc.!trigtype=trigtype /* type of trigger */
do until triggers="" /* add triggers (possibly just self */
parse upper var triggers atrig triggers ; atrig=strip(atrig)
foo=sysfiletree(atrig,stamp,'FT')
if stamp.0>0 then do
lk=cache_list.inc.!ntriggers+1
cache_list.inc.!trigger.lk=space(stamp.1)
cache_list.inc.!ntriggers=lk
end
end
cache_list.inc.!dafile=dafile
cache_list.inc.!size=dafilesize
cache_list.!size=cache_list.!size+dafilesize
cache_list.0=inc
/* get rid of old entries? */
do meow=1 to inc-1
if cache_list.meow=anfile & cache_list.meow.!host=host_nickname then do
foo=cache_del(meow)
leave
end
end
/* now check size of cache, and delete files if necessary */
if cache_list.!size>(cache_size*1000) then
foo=shrink_cache(0)
return ' ' /* no return info expected */
end
/* ========== here to check for a file in the cache */
do mm=1 to inc
if cache_list.mm=0 then iterate
if cache_list.mm=anfile & cache_list.mm.!host=host_nickname then do /* got a match -- check it's time and triggers */
cache_list.inc.!recent=nowtime
fexpire=cache_list.mm.!time+cache_list.mm.!duration
if fexpire<nowtime then do /* expired -- so no matdh */
foo=cache_del(mm)
return 0
end
do it0=1 to cache_list.mm.!ntriggers /* check all trigger files */
atrig=cache_list.mm.!trigger.it0
atrig=strip(word(atrig,4))
foo=sysfiletree(atrig,nowstamp,'FT')
oldstamp=cache_list.mm.!trigger.it0
if nowstamp.0=0 then do
Call pmprintf(" ERROR: ssi-cache trigger missing : " atrig)
foo=cache_del(mm); return 0
end
if CHECK_STAMP(nowstamp.1,oldstamp,cache_list.mm.!TRIGTYPE)=0 then do
foo=cache_del(mm); return 0
end
end
/* not expired, triggers okay; so use it */
/* call pmprintf(" ssi-cache, match: " mm' 'cache_list.mm.!type' 'cache_list.mm.!dafile)*/
/* last check -- make sure size is correct */
tst1=chars(cache_list.mm.!dafile); foo=stream(cache_list.mm.!dafile,'c','close')
if tst1<>cache_list.mm.!size then do
call pmprintf(' SSI-cache error: mismatch in cache sizes 'tst1 ',' cache_list.mm.!size', 'cache_list.mm.!dafile)
foo=cache_del(mm) /* delete this entry */
return 0
end
itype=cache_list.mm.!type
return itype' 'cache_list.mm.!dafile
end
end
return 0 /* don't got */
/*********/
check_stamp:procedure
parse upper arg stmp1,stmp2,atype
select
when atype='SIZE' then do
stmp1=strip(word(stmp1,2))
stmp2=strip(word(stmp2,2))
end
when atype='TIMEDATE' | atype='DATETIME' then do
stmp1=strip(word(stmp1,1))
stmp2=strip(word(stmp2,1))
end
when atype="ALL" then do
stmp1=strip(space(stmp1))
stmp2=strip(space(stmp2))
end
when atype='TIME' then do
stmp1=substr(strip(stmp1),10,5)
stmp2=substr(strip(stmp2),10,5)
end
when atype='DATE' then do
stmp1=substr(strip(stmp1),1,8)
stmp2=substr(strip(stmp2),1,8)
end
otherwise do
call pmprintf(' bad trigtype: 'atype)
return 0 /* should never happen */
end
end
/*call pmprintf(stmp1' !! 'stmp2) */
if stmp1=stmp2 then return 1 /* 1 means "okay", 0 means "out of sync */
return 0
/*********/
/* remove a cache entry */
cache_del:procedure expose cache_list. cache_size max_marked
parse arg nn
i1=cache_list.0
foo=sysfiledelete(strip(cache_list.nn.!dafile))
gsize=cache_list.nn.!size
cache_list.nn=0
cache_list.!size=cache_list.!size-gsize
/* call pmprintf(' deleted entry #' nn ', cache size now = ' cache_list.!size)*/
cache_list.!marked=cache_list.!marked+1
if cache_list.!marked > max_marked then foo=shrink_cache(0)
return foo
/*******/
do_status:procedure expose cache_list. addto host_nickname /* display current state */
parse arg iss0
iss=translate(iss0,' ','*+=?')
select
when strip(upper(word(iss,2)))='SHORT' then do
call lineout addto," "
call lineout addto," Current status of SSI-Cache "
call lineout addto,' # entries ' cache_list.0 ', bytes stored = ' cache_list.!size
if cache_list.0>0 then do
call lineout addto,' Host-nickname : File Cache-file , size #trigger_files most_recent_hit '
do mm=1 to cache_list.0
if cache_list.mm=0 then
call lineout addto,' Entry ' mm ' marked for deletion '
else
call lineout addto,cache_list.mm.!host ' : ' cache_list.mm ' ' ,
filespec('n',cache_list.mm.!dafile) ', ' cache_list.mm.!size ' ' cache_list.mm.!ntriggers ' ' cache_list.mm.!time
end
end /* clist>0 */
end
when words(iss)>1 then do
removes=substr(iss0,8)
removes=translate(removes,' ','+='||'000d0a'x)
removes=packur(removes); removes=upper(translate(removes,'\','/'))
removes=strip(word(removes,1))
call lineout addto,' '
call lineout addto,' Status info for cache entry: ' removes
do mm = 1 to cache_list.0
if cache_list.mm=removes & cache_list.mm.!Host=host_nickname then do
booger=cvtails(cache_list.mm.,stuff)
foo=arraysort(stuff)
do mm2=1 to stuff.0
aa=stuff.mm2
wow=cache_list.mm.aa
call lineout addto,' ' aa ' = 'wow
end
leave
end /* if */
end /* do loop */
end /* when words iss */
otherwise do /* show all the status stuff */
booger=cvtails(cache_list,stuff)
foo=arraysort(stuff)
do mm=1 to stuff.0
aa=stuff.mm
wow=cache_list.aa
call lineout addto,' ' aa ' = 'wow
end
end
end
call lineout addto
return 0
/*********/
/* shrink the cache
get rid of "marked for deletions". ALso, cut size of cache to 85% of max */
shrink_cache:procedure expose cache_list. cache_size
parse arg iwrite,tempfile
signal on error name aprob
signal on syntax name prob
ntmp=0
if cache_list.0=0 then do
call lineout tempfile,' '
call lineout tempfile,' SSI-Cache cleanup: No entries in cache list '
call lineout tempfile
return 1
end
wassize=cache_list.!size
wasentries=cache_list.0
nolds=0
ncleaned=0
/* This section is used to cut cache down to size */
if cache_list.!size>(cache_size*1000) then do
iwas=cache_list.!size
iww=0
do iw=1 to cache_list.0 /* make a sortable list */
if cache_list.iw<>0 then do
iww=iww+1
sht.iww=left(cache_list.iw.!recent,15)||' '||iw||' '||cache_list.iw.!size||' '||cache_list.iw
end
end
sht.0=iww
foo=arraysort(sht,1,,1,15,'A','N')
/* cut size of cache (by marking oldest for deletion, and deleting the cache file */
do iat=1 to sht.0
if cache_list.!size<(cache_size*850) then leave /*clean out some extra */
parse var sht.iat tt nth asize aname ; nth=strip(nth) ;asize=strip(asize)
cache_list.!size=cache_list.!size-asize
dafile=strip(dafile); foo=sysfiledelete(cache_list.nth.!dafile)
cache_list.nth=0 /* mark for deletion, along with prior marked items */
end
ntmp=0
end
/* now shrink cache_list array (remove marked for dletion enetries */
do iu=1 to cache_list.0
if cache_list.iu=0 then iterate
ntmp=ntmp+1
tmps.ntmp=cache_list.iu
foo=cvcopy(cache_list.iu.,tmps.ntmp.)
end
tmps.0=ntmp
tmps.!size=cache_list.!size
tmps.!marked=0
drop cache_list.
foo=cvcopy(tmps,cache_list)
drop tmps.; drop sht.
if iwrite=1 then do
call lineout tempfile,' '
call lineout tempfile,' SSI-Cache cleanup: Starting size (entries,bytes): 'wasentries ',' wassize
call lineout tempfile,' ending size (entries,bytes): 'cache_list.0 ',' cache_list.!size
call lineout tempfile
end
return 1
aprob:
signal off syntax
signal off error
call pmprintf(' Some kind of error in SSICACHE:cleanup procedure')
return 0